#include "nano2.h"
#include "AudioCaptureWidget.h"
#include "SerialWidget.h"
#include <QColorGroup>

#include <QtDebug>

nano2::nano2(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);

    timer = new QTimer();

    // setting loopTime 10 ms
    loopTime = 10;


    // setting parameters for nanoManipulator
    stepSize  = "speed ";
    move	  = "coarse ";
    noofStepsA = "1";
    noofStepsB = "1";
    noofStepsC = "1";
    stepCountA=0;
    stepCountB=0;
    stepCountC=0;


    // audio capture code
    qDebug()<<"Initializing Audio ....";
    mic = new AudioCaptureWidget();
    qDebug()<<"Done"<<endl<<endl;

    // creating and setting up com port
    port = new SerialWidget();

    // setting style of QLCD
    ui.stepCountA->setSegmentStyle(QLCDNumber::Flat);
    ui.stepCountB->setSegmentStyle(QLCDNumber::Flat);
    ui.stepCountC->setSegmentStyle(QLCDNumber::Flat);

    ui.speedA->setSegmentStyle(QLCDNumber::Flat);
    ui.speedB->setSegmentStyle(QLCDNumber::Flat);
    ui.speedC->setSegmentStyle(QLCDNumber::Flat);

    // making palette
    QPalette palette = ui.stepCountA->palette();
    palette.setColor(QPalette::Normal, QPalette::Foreground, Qt::black);
    palette.setColor(QPalette::Normal, QPalette::Background, Qt::black);
    palette.setColor(QPalette::Normal, QPalette::Light, Qt::black);
    palette.setColor(QPalette::Normal, QPalette::Dark, Qt::white);

    // assigning palette to LCD
    ui.stepCountA->setPalette(palette);
    ui.stepCountB->setPalette(palette);
    ui.stepCountC->setPalette(palette);

    ui.speedA->setPalette(palette);
    ui.speedB->setPalette(palette);
    ui.speedC->setPalette(palette);

    // setting parameters for dials
    ui.dialA->setMinimum(1);
    ui.dialA->setMaximum(100);
    ui.dialB->setMinimum(1);
    ui.dialB->setMaximum(100);
    ui.dialC->setMinimum(1);
    ui.dialC->setMaximum(100);
    ui.dialC->setNotchesVisible(1);

    // setting default threshold values in GUI
    ui.LLThreshold->setText(QString::number(mic->LLThreshold));
    ui.HLThreshold->setText(QString::number(mic->HLThreshold));
    ui.peakFreq->setText(QString::number(mic->peakFreqLimit));
    ui.loopTime->setText(QString::number(mic->notifyInterval));
    ui.minSteps->setText(QString::number(50000));


    // connecting dial to noofSteps
    connect(ui.dialC, SIGNAL(valueChanged(int)),this, SLOT(setNoOfStepsC()));
    connect(ui.dialB, SIGNAL(valueChanged(int)),this, SLOT(setNoOfStepsB()));
    connect(ui.dialA, SIGNAL(valueChanged(int)),this, SLOT(setNoOfStepsA()));

    // connecting joint movement buttons
    ui.jt1Clk->setCheckable(1);
    ui.jt1Aclk->setCheckable(1);
    ui.jt2Clk->setCheckable(1);
    ui.jt2Aclk->setCheckable(1);
    ui.jt3In->setCheckable(1);
    ui.jt3Out->setCheckable(1);

    connect(ui.jt1Clk, SIGNAL(clicked()), this, SLOT(jt1Clk()));
    connect(ui.jt1Aclk, SIGNAL(clicked()), this, SLOT(jt1Aclk()));
    connect(ui.jt2Clk, SIGNAL(clicked()), this, SLOT(jt2Clk()));
    connect(ui.jt2Aclk, SIGNAL(clicked()), this, SLOT(jt2Aclk()));
    connect(ui.jt3Out, SIGNAL(clicked()), this, SLOT(jt3Out()));
    connect(ui.jt3In, SIGNAL(clicked()), this, SLOT(jt3In()));

    // sends command to mm3a every 10 ms or interval set in GUI
    //connect(mic, SIGNAL(fftDone()), this, SLOT(jt3()));
    connect(mic->audioTimer, SIGNAL(timeout()), this, SLOT(moveJoint()));


    // stop experiment if end is reached or if stop button is pressed
    connect(mic,SIGNAL(trialComplete()), this, SLOT(stopButton()));
    connect(ui.stopButton, SIGNAL(clicked()),this, SLOT(stopButton()));

    // connecting reset buttons
    connect(ui.resetA, SIGNAL(clicked()), this, SLOT(resetA()));
    connect(ui.resetB, SIGNAL(clicked()), this, SLOT(resetB()));
    connect(ui.resetC, SIGNAL(clicked()), this, SLOT(resetC()));

    // Displaying step count on LCD
    connect(this, SIGNAL(countA(int)), ui.stepCountA, SLOT(display(int)));
    connect(this, SIGNAL(countB(int)), ui.stepCountB, SLOT(display(int)));
    connect(this, SIGNAL(countC(int)), ui.stepCountC, SLOT(display(int)));

    // connect dials to their respective functions
    connect(ui.dialA, SIGNAL(valueChanged(int)), ui.speedA, SLOT(display(int)));
    connect(ui.dialB, SIGNAL(valueChanged(int)), ui.speedB, SLOT(display(int)));
    connect(ui.dialC, SIGNAL(valueChanged(int)), ui.speedC, SLOT(display(int)));

    // connecting threshold buttons
    connect(ui.setThreshold, SIGNAL(clicked()), this, SLOT(setThreshold()));

    // plot edit button
    connect(ui.actionEdit, SIGNAL(triggered()), this, SLOT(plotEdit()));
    e = new editPlotWindow(this);
    e->hide();
    connect(e, SIGNAL(updatePlotAxis()), this, SLOT(updatePlotAxis()));

    this->setThreshold();
    // display fft widget
    mic->show();
    mic->move(QPoint(0,50));


    // setting manipulator enable checkbox to checked
    ui.manipEnable->setCheckState(Qt::Checked);
    enableManip = ui.manipEnable->checkState();

    connect(ui.manipEnable, SIGNAL(stateChanged(int)), this, SLOT(setEnableManip()));

}

nano2::~nano2()
{
    qDebug()<< "closing Program";
    //mic=NULL;
    //cam->close();

    //delete cam;
    //cam=NULL;
    port->close();
    delete port;
    port = NULL;
}



void nano2::setStepSize()
{
    command = stepSize + stepSizeStr;
    port->sendCommand(command);

}

void nano2::jt1Clk()
{
    joint = "A";
    dir = "-";
    command = move + joint + dir + noofStepsA;
    mic->start();

    ui.jt1Aclk->setChecked(0);
    ui.jt1Clk->setChecked(1);
    ui.jt2Aclk->setChecked(0);
    ui.jt2Clk->setChecked(0);
    ui.jt3In->setChecked(0);
    ui.jt3Out->setChecked(0);

}

void nano2::jt1Aclk()
{
    joint = "A";
    dir = "+";
    command = move + joint + dir + noofStepsA;
    mic->start();

    ui.jt1Aclk->setChecked(1);
    ui.jt1Clk->setChecked(0);
    ui.jt2Aclk->setChecked(0);
    ui.jt2Clk->setChecked(0);
    ui.jt3In->setChecked(0);
    ui.jt3Out->setChecked(0);
}

void nano2::jt2Clk()
{
    joint = "B";
    dir = "-";
    command = move + joint + dir + noofStepsB;
    mic->start();

    ui.jt1Aclk->setChecked(0);
    ui.jt1Clk->setChecked(0);
    ui.jt2Aclk->setChecked(0);
    ui.jt2Clk->setChecked(1);
    ui.jt3In->setChecked(0);
    ui.jt3Out->setChecked(0);

}

void nano2::jt2Aclk()
{
    joint = "B";
    dir = "+";
    command = move + joint + dir + noofStepsB;
    mic->start();

    ui.jt1Aclk->setChecked(0);
    ui.jt1Clk->setChecked(0);
    ui.jt2Aclk->setChecked(1);
    ui.jt2Clk->setChecked(0);
    ui.jt3In->setChecked(0);
    ui.jt3Out->setChecked(0);
}

void nano2::jt3Out()
{
    joint = "C";
    dir = "-";
    command = move + joint + dir + noofStepsC;
    mic->start();

    ui.jt1Aclk->setChecked(0);
    ui.jt1Clk->setChecked(0);
    ui.jt2Aclk->setChecked(0);
    ui.jt2Clk->setChecked(0);
    ui.jt3In->setChecked(0);
    ui.jt3Out->setChecked(1);
}

void nano2::jt3In()
{
    joint = "C";
    dir = "+";
    command = move + joint + dir + noofStepsC;
    mic->start();

    ui.jt1Aclk->setChecked(0);
    ui.jt1Clk->setChecked(0);
    ui.jt2Aclk->setChecked(0);
    ui.jt2Clk->setChecked(0);
    ui.jt3In->setChecked(1);
    ui.jt3Out->setChecked(0);
}



void nano2::moveJoint()
{
    if(enableManip==2) {
        port->sendCommand(command);
        port->receiveStatus();



            if(joint=="C") {
                stepCountC = stepCountC + 1;
                mic->actualStepCount = stepCountC;
                emit countC(stepCountC);
            }
            if(joint=="B") {
                stepCountB = stepCountB + 1;
                mic->actualStepCount = stepCountB;
                emit countB(stepCountB);
            }
            if(joint=="A") {
                stepCountA = stepCountA + 1;
                mic->actualStepCount = stepCountA;
                emit countA(stepCountA);
            }
        }


    //qDebug()<<command;

}

void nano2::resetA()
{
    stepCountA=0;
    emit countA(stepCountA);
    port->correctCommands =0;
    port->incorrectCommands =0;
}

void nano2::resetB()
{
    stepCountB=0;
    emit countB(stepCountB);
    port->correctCommands =0;
    port->incorrectCommands =0;
}

void nano2::resetC()
{
    stepCountC=0;
    emit countC(stepCountC);
    port->correctCommands =0;
    port->incorrectCommands =0;
}

void nano2::stopButton()
{
    ui.jt3Out->setDown(false);
    ui.jt3In->setDown(false);
    ui.stopButton->setDown(true);

    qDebug()<<port->correctCommands<<" " <<port->incorrectCommands;
    mic->stop();

    port->correctCommands =0;
    port->incorrectCommands =0;
}

void nano2::setNoOfStepsA()
{
    noofStepsA = QString::number(ui.dialA->value());
    command = move + joint + dir + noofStepsA;
}

void nano2::setNoOfStepsB()
{
    noofStepsB = QString::number(ui.dialB->value());
    command = move + joint + dir + noofStepsB;
}

void nano2::setNoOfStepsC()
{
    noofStepsC = QString::number(ui.dialC->value());
    command = move + joint + dir + noofStepsC;

}

void nano2::setThreshold()
{
    // connecting mic threshold to form threshold text box
    mic->HLThreshold    = ui.HLThreshold->text().toInt();
    mic->LLThreshold    = ui.LLThreshold->text().toInt();
    mic->stepCountLimit = ui.minSteps->text().toInt();
    mic->peakFreqLimit  = ui.peakFreq->text().toInt();
    mic->yLine[0] = (double)mic->HLThreshold;
    mic->yLine[1] = (double)mic->HLThreshold;

    //mic->thresholdLine->setSamples(mic->xLine, mic->yLine, 2);

    mic->fftPlot->setAxisScale(0,0,(mic->HLThreshold*2),(mic->HLThreshold*2)/5);
    mic->fftPlot->setAxisScale(2,2000,3000,100);
    //mic->audioSignalPlot->setAxisScale(0, -65000, 65000, 10000);
    // mic->audioSignalPlot->setAxisAutoScale(0, 1);
   // mic->audioSignalPlot->setAxisScale(0, 0, 100, 10);

    mic->notifyInterval = ui.loopTime->text().toInt();
    mic->audioTimer->setInterval(mic->notifyInterval);



    //mic->outputFile.open(QIODevice::ReadWrite);

    // mic->audio->start(&mic->outputFile);

    qDebug()<<"Configuration: "<< endl
                   <<"Higher limit threshold = "<<mic->HLThreshold<<endl
                   <<"Lower limit"<<mic->LLThreshold <<endl
                   << "NotifyInterval"<<mic->notifyInterval<<endl
                   <<"yline"<<mic->yLine[0]<<mic->yLine[1];
}



void nano2::actionClose()
{}

void nano2::actionOpen()
{}

void nano2::plotEdit()
{

    e->show();
    //editWindow->show();
}

void nano2::updatePlotAxis()
{
    int xmin = e->xLimitMin->toPlainText().toInt();
    int xmax = e->xLimitMax->toPlainText().toInt();
    int inc = (xmax-xmin)/10;
    mic->fftPlot->setAxisScale(2, xmin, xmax, inc);
    mic->fftPlot->replot();
    qDebug("updated");
}

void nano2::setEnableManip()
{
    enableManip = ui.manipEnable->checkState();
}
